﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Odbc;
using System.Windows.Controls;
using System.Windows.Controls.DataVisualization;
using System.Windows.Controls.DataVisualization.Charting;



namespace LetsGoToSchool
{
    public class Database
    {
        /// <summary>
        /// This class is used to connect and interface with the MySql Server running on the surface. It connects to a database called progress_data.
        /// All the methods in this class are static, since the database runs independently from the program, so that every class can interact with the Database at a given time
        /// </summary>
        private static string[] songList = { "Ode To Joy", "Twinkle Twinkle Little Star", "Mary Had A Little Lamb"};

        private readonly static string _myConnString = "DRIVER={MySQL ODBC 5.1 Driver}; SERVER=localhost; PORT = 3906; DATABASE=progress_data; USER=root; PASSWORD=password; OPTION = 0";

        //Adds a single image to the database with a given pathname and type
        public static void addImage(string path, string type)
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            int nextImageID;

            try
            {
                OdbcDataReader maxID = new OdbcCommand("select max(image_id) from images", currConnection).ExecuteReader();
                maxID.Read();
                nextImageID = maxID.GetInt32(0);
                nextImageID++;
            }
            catch (InvalidCastException)
            {
                nextImageID = 0;
            }
             
            
           string insertStatement = @"insert into images(image_id,pathname,coloring_flag,type,user) values ("+nextImageID+",'"+path+"',FALSE,'"+type+"','"+Main.CurrentUser+"')";
            
            OdbcCommand insertImage = new OdbcCommand(insertStatement, currConnection);
            insertImage.ExecuteNonQuery();

            currConnection.Close();
        }

        //returns a list of all the image types that have been created
        public static List<string> getAllTypes()
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            List<string> typeList = new List<string>();

            OdbcDataReader types = new OdbcCommand("select distinct type from images", currConnection).ExecuteReader();
            while (types.Read())
            {
                typeList.Add(types.GetString(0));
            }

            currConnection.Close();

            return typeList;

        }

        //removes a single image from the database
        public static void removeImage(string path)
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            string deleteStatement = @"delete from images where pathname='" + path + "'";

            OdbcCommand deleteImage = new OdbcCommand(deleteStatement, currConnection);
            deleteImage.ExecuteNonQuery();

            currConnection.Close();
        }

        //private method which gets all images from the database using a given query
        private static List<Image> getImages(string queryStatement)
        {
	        OdbcConnection currConnection = new OdbcConnection(_myConnString);
	        currConnection.Open();

            //get a list of all pathnames
	        OdbcCommand getImagesCommand = new OdbcCommand(queryStatement, currConnection);
	        OdbcDataReader queryResults = getImagesCommand.ExecuteReader();
	
	        List<Image> imageList = new List<Image>();

            //create images
            while (queryResults.Read())
            {
                string path = queryResults.GetString(0);
                string type = queryResults.GetString(1);
                Image newImage = Utils.loadImage(path);
                newImage.Tag = type;
                imageList.Add(newImage);
            }

            currConnection.Close();
	        return imageList;
        }

        //Calls getImages, return all images with no type specified
        public static List<Image> getAllImages()
        {
	        string queryStatement = "select pathname, type from images";
	        return getImages(queryStatement);
        }

        //calls getImages, returns all images with type specified
        public static List<string> getAllMyImages(string type)
        {
	        string queryStatement = "select pathname, type from images where type='"+type+"'";
	        return getMyImages(queryStatement);
        }

        //Gets all images
        private static List<string> getMyImages(string queryStatement)
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            OdbcCommand getImagesCommand = new OdbcCommand(queryStatement, currConnection);
            OdbcDataReader queryResults = getImagesCommand.ExecuteReader();

            List<string> imagePathList = new List<string>();

            while (queryResults.Read())
            {
                string path = queryResults.GetString(0);
                string type = queryResults.GetString(1);
                Image newImage = Utils.loadImage(path);
                newImage.Tag = type;
                imagePathList.Add(path);
            }

            currConnection.Close();
            return imagePathList;
        }

        //Sets the value in the 'type' column in the images table for an entry with a given pathname
        public static void setImageType(string path, string type)
        {
           OdbcConnection currConnection = new OdbcConnection(_myConnString);
           currConnection.Open();

           OdbcCommand setTypeCommand = new OdbcCommand("insert into images(type) values('"+type+"')", currConnection);
           setTypeCommand.ExecuteNonQuery();

           currConnection.Close();
        }

        //returns a list of all accounts
        public static List<string> getAllAccounts()
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            OdbcCommand getAccountsCommand = new OdbcCommand("select login from accounts", currConnection);
            OdbcDataReader queryResults = getAccountsCommand.ExecuteReader();

            List<string> accountList = new List<string>();

            while (queryResults.Read())
            {
                string login = queryResults.GetString(0);
                accountList.Add(login);
            }

            currConnection.Close();
            return accountList;
        }

        //creates an account by adding the name to accounts table
        public static void createAccount(string newLogin)
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            int nextAccountID;

           try
            {
                OdbcDataReader maxID = new OdbcCommand("select max(login_id) from accounts", currConnection).ExecuteReader();
                maxID.Read();
                nextAccountID = maxID.GetInt32(0);
                nextAccountID++;
            }
            catch (InvalidCastException)
            {
                nextAccountID = 0;
            }

            OdbcCommand add_account = new OdbcCommand("insert into accounts(login_id,login) values('"+nextAccountID+"','"+newLogin+"')",currConnection);
            
            add_account.ExecuteNonQuery();
          
            currConnection.Close();

        }

        //Removes an account from the database. Removes the login from the accounts table and all data in subsequent tables
        public static void removeAccount(string loginToRemove)
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            OdbcCommand add_account = new OdbcCommand("delete from accounts where login='"+loginToRemove+"'", currConnection);
            OdbcCommand drop_memory_tbl = new OdbcCommand("delete from memory where user='"+loginToRemove+"'", currConnection);
            OdbcCommand drop_music_tbl = new OdbcCommand("delete from music where user='" + loginToRemove + "'", currConnection);
            OdbcCommand drop_doodle_tbl = new OdbcCommand("delete from doodle where user='" + loginToRemove + "'", currConnection);

            //must remove the data for that user from all tables
            add_account.ExecuteNonQuery();
            drop_memory_tbl.ExecuteNonQuery();
            drop_music_tbl.ExecuteNonQuery();
            drop_doodle_tbl.ExecuteNonQuery();

            currConnection.Close();

        }


        //writes a row of memory data to the 'memory' table
        public static void writeMemorySessionData(MemorySessionNode node)
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            int nextSessionID;

            try
            {
                OdbcDataReader maxID = new OdbcCommand("select max(session_id) from memory where user='" + Main.CurrentUser +"'", currConnection).ExecuteReader();
                maxID.Read();
                nextSessionID = maxID.GetInt32(0);
                nextSessionID++;
            }
            catch (InvalidCastException)
            {
                nextSessionID = 0;
            }

            string insertStatement = @"insert into memory(session_id,user,time,moves,difficulty) values (" + nextSessionID + ",'" + Main.CurrentUser+ "'," + node.getTime().TotalMinutes + "," + node.getMoves() + "," + node.getDifficutly() + ")";
            OdbcCommand insertRow = new OdbcCommand(insertStatement, currConnection);
            insertRow.ExecuteNonQuery();
            currConnection.Close();

        }

        //Writes a row of data to the 'music' table
        public static void writeMusicSessionData(MusicStatNode node)
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            int nextSessionID;

            try
            {
                OdbcDataReader maxID = new OdbcCommand("select max(session_id) from music where user='" + Main.CurrentUser +"'", currConnection).ExecuteReader();
                maxID.Read();
                nextSessionID = maxID.GetInt32(0);
                nextSessionID++;
            }
            catch (InvalidCastException)
            {
                nextSessionID = 0;
            }

            string insertStatement = @"insert into music(session_id,user,percent_correct,song,time,difficulty) values (" + nextSessionID + ",'" + Main.CurrentUser+ "'," + node.getPercentCorrect() + ",'" + node.getSong() + "'," + node.getTime().TotalMinutes + "," + node.getDifficulty() + ")";
            OdbcCommand insertRow = new OdbcCommand(insertStatement, currConnection);
            insertRow.ExecuteNonQuery();
            currConnection.Close();

        }

        //writes a row of data to the 'doodle' table;
        public static void writeDoodleSessionData(DoodleStatNode node)
        {

            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            int nextSessionID;

            try
            {
                OdbcDataReader maxID = new OdbcCommand("select max(session_id) from doodle where user='" + Main.CurrentUser +"'", currConnection).ExecuteReader();
                maxID.Read();
                nextSessionID = maxID.GetInt32(0);
                nextSessionID++;
            }
            catch (InvalidCastException)
            {
                nextSessionID = 0;
            }

            string insertStatement = @"insert into doodle(session_id,user,time) values (" + nextSessionID + ",'" + Main.CurrentUser +"'," + node.getDuration().TotalMinutes + ")";
            OdbcCommand insertRow = new OdbcCommand(insertStatement, currConnection);
            insertRow.ExecuteNonQuery();
            currConnection.Close();
        }

        //Creates a set of (x,y) pairs to be entered as data into the memory graph in the progress report
        //x is the session number, y is the time
        public static KeyValuePair<int, double>[] getMemoryGraphData(int diff)
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            int count;
            try
            {

                OdbcCommand getCount = new OdbcCommand("select count(session_id) from memory where difficulty=" + diff +" and user='" +Main.CurrentUser +"'", currConnection);
                OdbcDataReader result = getCount.ExecuteReader();
                result.Read();
                count = result.GetInt32(0);
                count++;
            }
            catch (InvalidCastException)
            {
                count = 0;
            }

            KeyValuePair<int, double>[] dataPointList = new KeyValuePair<int, double>[count];

            if (count != 0)
            {
                OdbcCommand getDataCommand = new OdbcCommand("select session_id,time from memory where difficulty=" + diff +" and user='" +Main.CurrentUser+"'", currConnection);
                OdbcDataReader memData = getDataCommand.ExecuteReader();
                int i = 0;
                while (memData.Read())
                {
                    dataPointList[i] = new KeyValuePair<int, double>(i, memData.GetDouble(1));
                    i++;
                }

            }
            return dataPointList;

        }

        //Creates a set of (x,y) pairs to be entered as data into the muysic graph in the progress report
        //x is the session number, y is the accuracy
        public static KeyValuePair<int, double>[] getMusicGraphData()
        {
            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            int count;
            try
            {
                OdbcCommand getCount = new OdbcCommand("select count(session_id) from music where user='" + Main.CurrentUser +"'", currConnection);
                OdbcDataReader result = getCount.ExecuteReader();
                result.Read();
                count = result.GetInt32(0);
                count++;
            }
            catch (InvalidCastException)
            {
                count = 0;
            }

            KeyValuePair<int, double>[] dataPointList = new KeyValuePair<int, double>[count];

            if (count != 0)
            {


                OdbcCommand getDataCommand = new OdbcCommand("select session_id,percent_correct from music where user='" + Main.CurrentUser +"'", currConnection);
                OdbcDataReader musData = getDataCommand.ExecuteReader();
                int i = 0;
                while (musData.Read())
                {
                    dataPointList[i] = new KeyValuePair<int, double>(musData.GetInt32(0), musData.GetDouble(1));
                    i++;
                }

            }
            return dataPointList;

        }

        /*
         * This class creates ProgressDataNode. This node contains as fields all of the data that is displayed in the progress report
         * This node is generated everytime the progress report is none, and its fields are used to poplate the text boxes in the report
         * 
         * 
         */
        public static ProgressDataNode generateReport(string login)
        {
            ///ProgressDataNode node = new ProgressDataNode();
            //Overall Stats
            TimeSpan totalPlaytime;
            TimeSpan totalMemoryPlaytime;
            TimeSpan totalMusicPlaytime;
            TimeSpan totalDoodlePlaytime;
            int totalSessions;
            int totalMemorySessions;
            int totalMusicSessions;
            int totalDoodleSessions;
            //memeory stats
            TimeSpan e_fastestTime;
            TimeSpan m_fastestTime;
            TimeSpan h_fastestTime;
            TimeSpan e_averageTime;
            TimeSpan m_averageTime;
            TimeSpan h_averageTime;
            double e_averageMoves;
            double m_averageMoves;
            double h_averageMoves;
            //music stats
            string _bestSong;
            string _favoriteSong;
            double _bestAccuracy;
            double _averageAccuracy;



            OdbcConnection currConnection = new OdbcConnection(_myConnString);
            currConnection.Open();

            //OVERALL STATS
            // Playtime Stats -- calculates the number of minutes spent playing each game and the total
            double memoryMinutes;
            double musicMinutes;
            double doodleMinutes;
            try
            {
                OdbcCommand getPlaytime = new OdbcCommand("select sum(time) from memory where user='" + login + "'", currConnection);
                OdbcDataReader minutesResult = getPlaytime.ExecuteReader();
                minutesResult.Read();
                memoryMinutes = minutesResult.GetDouble(0);
            }
            catch (InvalidCastException)
            {
                memoryMinutes = 0;
            }
            try
            {
                OdbcCommand getPlaytime = new OdbcCommand("select sum(time) from music where user='" + login + "'", currConnection);
                OdbcDataReader minutesResult = getPlaytime.ExecuteReader();
                minutesResult.Read();
                musicMinutes = minutesResult.GetDouble(0);
            }
            catch (InvalidCastException)
            {
                musicMinutes = 0;
            }
            try
            {
                OdbcCommand getPlaytime = new OdbcCommand("select sum(time) from doodle where user='" + login + "'", currConnection);
                OdbcDataReader minutesResult = getPlaytime.ExecuteReader();
                minutesResult.Read();
                doodleMinutes = minutesResult.GetDouble(0);
            }
            catch (InvalidCastException)
            {
                doodleMinutes = 0;
            }

            totalPlaytime = TimeSpan.FromMinutes(memoryMinutes + musicMinutes + doodleMinutes);
            totalMemoryPlaytime = TimeSpan.FromMinutes(memoryMinutes);
            totalMusicPlaytime = TimeSpan.FromMinutes(musicMinutes);
            totalDoodlePlaytime = TimeSpan.FromMinutes(doodleMinutes);

            //SDession Number Stats -- calculates the total number of sessions for each game and the total
            try
            {
                OdbcCommand getSessions = new OdbcCommand("select count(session_id) from memory where user='" + login + "'", currConnection);
                OdbcDataReader numSessions = getSessions.ExecuteReader();
                numSessions.Read();
                totalMemorySessions = numSessions.GetInt32(0);
            }
            catch (InvalidCastException)
            {
                totalMemorySessions = 0;
            }
            try
            {
                OdbcCommand getSessions = new OdbcCommand("select count(session_id) from music where user='" + login + "'", currConnection);
                OdbcDataReader numSessions = getSessions.ExecuteReader();
                numSessions.Read();
                totalMusicSessions = numSessions.GetInt32(0);
            }
            catch (InvalidCastException)
            {
                totalMusicSessions = 0;
            }
            try
            {
                OdbcCommand getSessions = new OdbcCommand("select count(session_id) from doodle where user='" + login + "'", currConnection);
                OdbcDataReader numSessions = getSessions.ExecuteReader();
                numSessions.Read();
                totalDoodleSessions = numSessions.GetInt32(0);
            }
            catch (InvalidCastException)
            {
                totalDoodleSessions = 0;
            }
            totalSessions = totalMemorySessions + totalMusicSessions + totalDoodleSessions;

            //MEMORY STATS
            //Fastest Time
            //Difficulty -- EASY
            try
            {
                OdbcCommand getFastestTimeE = new OdbcCommand("select min(time) from memory where difficulty=0 and user='" + login + "'", currConnection);
                OdbcDataReader timeResultE = getFastestTimeE.ExecuteReader();
                timeResultE.Read();
                double efastestMinutes = timeResultE.GetDouble(0);
                e_fastestTime = TimeSpan.FromMinutes(efastestMinutes);
            }
            catch (InvalidCastException)
            {
                e_fastestTime = new TimeSpan(0);
            }
            //MEDIUM
            try
            {
                OdbcCommand getFastestTimeM = new OdbcCommand("select min(time) from memory where difficulty=1 and user='" + login + "'", currConnection);
                OdbcDataReader timeResultM = getFastestTimeM.ExecuteReader();
                timeResultM.Read();
                double mfastestMinutes = timeResultM.GetDouble(0);
                m_fastestTime = TimeSpan.FromMinutes(mfastestMinutes);
            }
            catch (InvalidCastException)
            {
                m_fastestTime = new TimeSpan(0);
            }
            //HARD
            try
            {
                OdbcCommand getFastestTimeH = new OdbcCommand("select min(time) from memory where difficulty=2 and user='" + login + "'", currConnection);
                OdbcDataReader timeResultH = getFastestTimeH.ExecuteReader();
                timeResultH.Read();
                double hfastestMinutes = timeResultH.GetDouble(0);
                h_fastestTime = TimeSpan.FromMinutes(hfastestMinutes);
            }
            catch (InvalidCastException)
            {
                h_fastestTime = new TimeSpan(0);
            }

            //Average Time -- the average time taken across all sessions
            int session_countE;
            try
            {
                OdbcCommand getSessionsE = new OdbcCommand("select count(session_id) from memory where difficulty=0 and user='" + login + "'", currConnection);
                OdbcDataReader countResult = getSessionsE.ExecuteReader();
                countResult.Read();
                session_countE = countResult.GetInt32(0);
            }
            catch (InvalidCastException)
            {
                session_countE = 0;
            }

            int session_countM;
            try
            {
                OdbcCommand getSessionsM = new OdbcCommand("select count(session_id) from memory where difficulty=1 and user='" + login + "'", currConnection);
                OdbcDataReader countResult = getSessionsM.ExecuteReader();
                countResult.Read();
                session_countM = countResult.GetInt32(0);
            }

            catch (InvalidCastException)
            {
                session_countM = 0;
            }
            int session_countH;
            try
            {
                OdbcCommand getSessionsH = new OdbcCommand("select count(session_id) from memory where difficulty=2 and user='"+login+"'", currConnection);
                OdbcDataReader countResult = getSessionsH.ExecuteReader();
                countResult.Read();
                session_countH = countResult.GetInt32(0);
            }
            catch (InvalidCastException)
            {
                session_countH = 0;
            }

            double mem_min_e;
            try
            {
                OdbcCommand getTimeE = new OdbcCommand("select sum(time) from memory where difficulty=0 and user='" + login + "'", currConnection);
                OdbcDataReader countResult = getTimeE.ExecuteReader();
                countResult.Read();
                mem_min_e = countResult.GetDouble(0);
            }
            catch (InvalidCastException)
            {
                mem_min_e = 0;
            }
            double mem_min_m;
            try
            {
                OdbcCommand getTimeM = new OdbcCommand("select sum(time) from memory where difficulty=1 and user='" + login + "'", currConnection);
                OdbcDataReader countResult = getTimeM.ExecuteReader();
                countResult.Read();
                mem_min_m = countResult.GetDouble(0);
            }
            catch (InvalidCastException)
            {
                mem_min_m = 0;
            }
            double mem_min_h;
            try
            {
                OdbcCommand getTimeH = new OdbcCommand("select sum(time) from memory where difficulty=2 and user='" + login + "'", currConnection);
                OdbcDataReader countResult = getTimeH.ExecuteReader();
                countResult.Read();
                mem_min_h = countResult.GetDouble(0);
            }
            catch (InvalidCastException)
            {
                mem_min_h = 0;
            }
            double e_averageMinutes;
            double m_averageMinutes;
            double h_averageMinutes;
            if (session_countE != 0)
            {
                e_averageMinutes = mem_min_e / (double) session_countE;
            }
            else
                e_averageMinutes = 0;

            e_averageTime = TimeSpan.FromMinutes(e_averageMinutes);
            if (session_countM != 0)
            {
                m_averageMinutes = mem_min_m / (double) session_countM;
            }
            else
                m_averageMinutes = 0;
            m_averageTime = TimeSpan.FromMinutes(m_averageMinutes);

            if (session_countH != 0)
            {
                h_averageMinutes = mem_min_h / (double) session_countH;
            }
            else
                h_averageMinutes = 0;

            h_averageTime = TimeSpan.FromMinutes(h_averageMinutes);



            //Average Moves -- the average number of moves taken to complete the game over all sessions
            try
            {
                OdbcCommand getMoves = new OdbcCommand("select sum(moves) from memory where difficulty=0 and user='" + login + "'", currConnection);
                OdbcDataReader moves = getMoves.ExecuteReader();
                OdbcCommand getGames = new OdbcCommand("select count(session_id) from memory where user='" + login + "'", currConnection);
                OdbcDataReader games = getGames.ExecuteReader();
                games.Read();
                moves.Read();
                int numGames = games.GetInt32(0);
                int numMoves = moves.GetInt32(0);
                e_averageMoves = ((double)numMoves) / ((double)numGames);
            }
            catch (InvalidCastException)
            {
                e_averageMoves = 0;
            }

            try
            {
                OdbcCommand getMoves = new OdbcCommand("select sum(moves) from memory where difficulty=1 and user='" + login + "'", currConnection);
                OdbcDataReader moves = getMoves.ExecuteReader();
                OdbcCommand getGames = new OdbcCommand("select count(session_id) from memory where user='" + login + "'", currConnection);
                OdbcDataReader games = getGames.ExecuteReader();
                games.Read();
                moves.Read();
                int numGames = games.GetInt32(0);
                int numMoves = moves.GetInt32(0);
                m_averageMoves = ((double)numMoves) / ((double)numGames);
            }
            catch (InvalidCastException)
            {
                m_averageMoves = 0;
            }
            try
            {
                OdbcCommand getMoves = new OdbcCommand("select sum(moves) from memory where difficulty=2 and user='" + login + "'", currConnection);
                OdbcDataReader moves = getMoves.ExecuteReader();
                OdbcCommand getGames = new OdbcCommand("select count(session_id) from memory where user='" + login + "'", currConnection);
                OdbcDataReader games = getGames.ExecuteReader();
                games.Read();
                moves.Read();
                int numGames = games.GetInt32(0);
                int numMoves = moves.GetInt32(0);
                h_averageMoves = ((double)numMoves) / ((double)numGames);
            }
            catch (InvalidCastException)
            {
                h_averageMoves = 0;
            }

            //MUSIC STATS
            //Best Song -- the song on which the user has given the best performance
            try
            {
                OdbcCommand getBestSong = new OdbcCommand("select song from music where percent_correct= (select max(percent_correct) from music where user='" + login + "') and user='" + login + "'", currConnection);
                OdbcDataReader song = getBestSong.ExecuteReader();
                song.Read();
                _bestSong = song.GetString(0);
            }
            catch (InvalidOperationException)
            {
                _bestSong = "none";
            }


            //Best Accuracy -- the highest percent correct notes the user has achieved
            try
            {
                OdbcCommand getBestAcc = new OdbcCommand("select max(percent_correct) from music where user='" + login + "'", currConnection);
                OdbcDataReader acc = getBestAcc.ExecuteReader();
                acc.Read();
                _bestAccuracy = acc.GetDouble(0);
            }
            catch (InvalidCastException)
            {
                _bestAccuracy = 0;
            }


            //Favorite Song -- which ever song has been played most often
            int count = 0;
            _favoriteSong = "";
            foreach (string song in songList)
            {
                try
                {
                    OdbcCommand getFavSong = new OdbcCommand("select count(song) from music where song= '" + song + "' and user='" + login + "'", currConnection);
                    OdbcDataReader fav = getFavSong.ExecuteReader();
                    fav.Read();
                    int songCount = fav.GetInt32(0);
                    if (songCount >= count)
                    {
                        _favoriteSong = song;
                    }
                }
                catch (InvalidOperationException)
                {
                    _favoriteSong = "none";
                }

            }


            //Average Accuracy -- the average percent correct notes for all sessions
            double _totalPerent;
            try
            {
                OdbcCommand getSumAcc = new OdbcCommand("select sum(percent_correct) from music where user='" + login + "'", currConnection);
                OdbcDataReader sumAcc = getSumAcc.ExecuteReader();
                sumAcc.Read();
                _totalPerent = sumAcc.GetDouble(0);
            }
            catch (InvalidCastException)
            {
                _totalPerent = 0;
            }


            double _Sessions;
            try
            {
                OdbcCommand getSumAcc = new OdbcCommand("select count(percent_correct) from music where user='" + login + "'", currConnection);
                OdbcDataReader sumAcc = getSumAcc.ExecuteReader();
                sumAcc.Read();
                _Sessions = sumAcc.GetDouble(0);
            }
            catch (InvalidCastException)
            {
                _Sessions = 0;
            }


            _averageAccuracy = _totalPerent / _Sessions;

            //Once all calculations have been made, all the fields in the node must be set. 

            ProgressDataNode node = new ProgressDataNode();

            node._TotalPlaytime = totalPlaytime;
            node._TotalMemoryPlaytime = totalMemoryPlaytime;
            node._TotalMusicPlaytime = totalMusicPlaytime;
            node._TotalDoodlePlaytime = totalDoodlePlaytime;

            node._TotalSessions = totalSessions;
            node._TotalMemorySessions = totalMemorySessions;
            node._TotalMusicSessions = totalMusicSessions;
            node._TotalDoodleSessions = totalDoodleSessions;

            node.E_FastestTime = e_fastestTime;
            node.M_FastestTime = m_fastestTime;
            node.H_FastestTime = h_fastestTime;

            node.E_AverageTime = e_averageTime;
            node.M_AverageTime = m_averageTime;
            node.H_AverageTime = h_averageTime;

            node.E_AverageMoves = e_averageMoves;
            node.M_AverageMoves = m_averageMoves;
            node.H_AverageMoves = h_averageMoves;

            node.BestSong = _bestSong;
            node.FavoriteSong = _favoriteSong;
            node.BestAccuracy = _bestAccuracy;
            node.AverageAccuracy = _averageAccuracy;




            return node;
        }
    }
}
